// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILATION_STATISTICS_H_
#define V8_COMPILATION_STATISTICS_H_

#include <map>
#include <string>

#include "src/allocation.h"
#include "src/base/platform/time.h"

namespace v8 {
namespace internal {

    class OptimizedCompilationInfo;
    class CompilationStatistics;

    struct AsPrintableStatistics {
        const CompilationStatistics& s;
        const bool machine_output;
    };

    class CompilationStatistics final : public Malloced {
    public:
        CompilationStatistics() = default;

        class BasicStats {
        public:
            BasicStats()
                : total_allocated_bytes_(0)
                , max_allocated_bytes_(0)
                , absolute_max_allocated_bytes_(0)
            {
            }

            void Accumulate(const BasicStats& stats);

            base::TimeDelta delta_;
            size_t total_allocated_bytes_;
            size_t max_allocated_bytes_;
            size_t absolute_max_allocated_bytes_;
            std::string function_name_;
        };

        void RecordPhaseStats(const char* phase_kind_name, const char* phase_name,
            const BasicStats& stats);

        void RecordPhaseKindStats(const char* phase_kind_name,
            const BasicStats& stats);

        void RecordTotalStats(size_t source_size, const BasicStats& stats);

    private:
        class TotalStats : public BasicStats {
        public:
            TotalStats()
                : source_size_(0)
            {
            }
            uint64_t source_size_;
        };

        class OrderedStats : public BasicStats {
        public:
            explicit OrderedStats(size_t insert_order)
                : insert_order_(insert_order)
            {
            }
            size_t insert_order_;
        };

        class PhaseStats : public OrderedStats {
        public:
            PhaseStats(size_t insert_order, const char* phase_kind_name)
                : OrderedStats(insert_order)
                , phase_kind_name_(phase_kind_name)
            {
            }
            std::string phase_kind_name_;
        };

        friend std::ostream& operator<<(std::ostream& os,
            const AsPrintableStatistics& s);

        typedef OrderedStats PhaseKindStats;
        typedef std::map<std::string, PhaseKindStats> PhaseKindMap;
        typedef std::map<std::string, PhaseStats> PhaseMap;

        TotalStats total_stats_;
        PhaseKindMap phase_kind_map_;
        PhaseMap phase_map_;
        base::Mutex record_mutex_;

        DISALLOW_COPY_AND_ASSIGN(CompilationStatistics);
    };

    std::ostream& operator<<(std::ostream& os, const AsPrintableStatistics& s);

} // namespace internal
} // namespace v8

#endif // V8_COMPILATION_STATISTICS_H_
